6b9b27
@@ -26,6 +26,8 @@
import org.springframework.data.domain.Slice;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.repository.core.EntityMetadata;
 import org.springframework.data.repository.core.RepositoryMetadata;
+import org.springframework.data.repository.util.QueryExecutionConverters;
+import org.springframework.data.util.ClassTypeInformation;
 import org.springframework.data.util.ReflectionUtils;
 import org.springframework.util.Assert;
 
@@ -40,6 +42,7 @@
public class QueryMethod {
 
 	private final RepositoryMetadata metadata;
 	private final Method method;
+	private final Class<?> unwrappedReturnType;
 	private final Parameters<?, ?> parameters;
 
 	private Class<?> domainClass;
@@ -64,6 +67,7 @@
public class QueryMethod {
 		}
 
 		this.method = method;
+		this.unwrappedReturnType = potentiallyUnwrapReturnTypeFor(method);
 		this.parameters = createParameters(method);
 		this.metadata = metadata;
 
@@ -140,8 +144,8 @@
public class QueryMethod {
 			Class<?> repositoryDomainClass = metadata.getDomainType();
 			Class<?> methodDomainClass = metadata.getReturnedDomainClass(method);
 
-			this.domainClass = repositoryDomainClass == null || repositoryDomainClass.isAssignableFrom(methodDomainClass) ? methodDomainClass
-					: repositoryDomainClass;
+			this.domainClass = repositoryDomainClass == null || repositoryDomainClass.isAssignableFrom(methodDomainClass)
+					? methodDomainClass : repositoryDomainClass;
 		}
 
 		return domainClass;
@@ -163,9 +167,9 @@
public class QueryMethod {
 	 */
 	public boolean isCollectionQuery() {
 
-		Class<?> returnType = method.getReturnType();
 		return !(isPageQuery() || isSliceQuery())
-				&& org.springframework.util.ClassUtils.isAssignable(Iterable.class, returnType) || returnType.isArray();
+				&& org.springframework.util.ClassUtils.isAssignable(Iterable.class, unwrappedReturnType)
+				|| unwrappedReturnType.isArray();
 	}
 
 	/**
@@ -175,9 +179,7 @@
public class QueryMethod {
 	 * @since 1.8
 	 */
 	public boolean isSliceQuery() {
-
-		Class<?> returnType = method.getReturnType();
-		return !isPageQuery() && org.springframework.util.ClassUtils.isAssignable(Slice.class, returnType);
+		return !isPageQuery() && org.springframework.util.ClassUtils.isAssignable(Slice.class, unwrappedReturnType);
 	}
 
 	/**
@@ -186,9 +188,7 @@
public class QueryMethod {
 	 * @return
 	 */
 	public final boolean isPageQuery() {
-
-		Class<?> returnType = method.getReturnType();
-		return org.springframework.util.ClassUtils.isAssignable(Page.class, returnType);
+		return org.springframework.util.ClassUtils.isAssignable(Page.class, unwrappedReturnType);
 	}
 
 	/**
@@ -216,7 +216,7 @@
public class QueryMethod {
 	 * @since 1.10
 	 */
 	public boolean isStreamQuery() {
-		return ReflectionUtils.isJava8StreamType(method.getReturnType());
+		return ReflectionUtils.isJava8StreamType(unwrappedReturnType);
 	}
 
 	/**
@@ -236,4 +236,14 @@
public class QueryMethod {
 	public String toString() {
 		return method.toString();
 	}
+
+	private static Class<? extends Object> potentiallyUnwrapReturnTypeFor(Method method) {
+
+		if (QueryExecutionConverters.supports(method.getReturnType())) {
+			// unwrap only one level to handle cases like Future<List<Entity>> correctly.
+			return ClassTypeInformation.fromReturnTypeOf(method).getComponentType().getType();
+		}
+
+		return method.getReturnType();
+	}
 }
